/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package my.ClientTorrent;

import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
/**
 *
 * @author Wico
 */
public class FileTorrent {
    private String filename;
    private int pieceLength;
    private ArrayList<String> pieces;
    private String announce;
    private long fileSize;
    private int piecesAmount;
    
    public FileTorrent()
    {
    }
    
    public static FileTorrent ConvertToTorrent(File filein, String linkTraker,int pieceLength) throws FileNotFoundException, NoSuchAlgorithmException, IOException
    {
        FileTorrent result = new FileTorrent();
        result.setFilename(filein.getName());
        result.setFileSize(filein.length());
        result.setAnnounce(linkTraker);
        //System.out.println("Announce = " + result.getAnnounce());
        //System.out.println("File Name = " +result.getFilename());
        //System.out.println("File Size = " + result.getFileSize());
        
        if (pieceLength !=0) result.setPieceLength(pieceLength);
        else
        {
            if (result.getFileSize() <= 48000*1024) // ukuran piece 32KB untuk file <= 48000KB
                result.setPieceLength((32*1024));
            else if (result.getFileSize() <= 2*48000*1024) // ukuran piece 32KB untuk file <= 48000KB
                result.setPieceLength((64*1024));
            else if (result.getFileSize() <= 4*48000*1024) // ukuran piece 32KB untuk file <= 48000KB
                result.setPieceLength((128*1024));
            else if (result.getFileSize() <= 8*48000*1024) // ukuran piece 32KB untuk file <= 48000KB
                result.setPieceLength((256*1024));
            else if (result.getFileSize() <= 16*48000*1024) // ukuran piece 32KB untuk file <= 48000KB
                result.setPieceLength((512*1024));
            else if (result.getFileSize() <= 32*48000*1024) // ukuran piece 32KB untuk file <= 48000KB
                result.setPieceLength((1024*1024));
            else if (result.getFileSize() <= 64*48000*1024) // ukuran piece 32KB untuk file <= 48000KB
                result.setPieceLength((2048*1024));
            else if (result.getFileSize() <= 128*48000*1024) // ukuran piece 32KB untuk file <= 48000KB
                result.setPieceLength((4096*1024));
            else 
                result.setPieceLength((4096*1024));
        }
        
        //System.out.println("Piece Length = " + result.getPieceLength());
        
        result.setPiecesAmount((int)Math.ceil((double)result.getFileSize()/result.getPieceLength()));
        //System.out.println("Piece Ammount = " + result.getPiecesAmount());
        
        
        ArrayList<String> tempPieces = new ArrayList<String>();
        FileInputStream fis = new FileInputStream(filein);
        for (int i = 0; i < result.getPiecesAmount(); i++)
        {
            byte[] buffer = new byte[result.getPieceLength()];
            String tempString = new String();
            try {fis.read(buffer);} catch (IOException ex) {ex.printStackTrace();}
            MessageDigest md = MessageDigest.getInstance("SHA");
            md.update(buffer);
            byte[] digest = md.digest();
            for (int j = 0; j < digest.length; j++)
            {
               tempString += String.format("%02X", digest[j] & 0xff);
            }
            tempPieces.add(tempString);
          //  System.out.println("piece-" + i + " = " + tempString);
        }
        fis.close();
        result.setPieces(tempPieces);
        return result;  
    }
    
    public void SaveTo(String filename) throws IOException
    {
        FileWriter fw = new FileWriter(filename);
        fw.write(announce + "\n");
        fw.write(this.filename + "\n");
        fw.write(fileSize + "\n");
        fw.write(pieceLength + "\n");
        fw.write(piecesAmount + "\n");
        for (int i = 0; i < piecesAmount; i++)        
        {
            fw.write(pieces.get(i) + "\n");
        }
        fw.close();
    }
    
    public static FileTorrent LoadFrom(String filename) throws FileNotFoundException, IOException
    {
        FileTorrent result = new FileTorrent();
        BufferedReader br = new BufferedReader(new FileReader(filename));
        ArrayList<String> tempArray = new ArrayList<String>();
        
        result.setAnnounce(br.readLine());
        result.setFilename(br.readLine());
        result.setFileSize(Long.parseLong(br.readLine()));
        result.setPieceLength(Integer.parseInt(br.readLine()));
        result.setPiecesAmount(Integer.parseInt(br.readLine()));
        for (int i = 0; i < result.getPiecesAmount(); i++)
        {
            tempArray.add(br.readLine());
        }
        result.setPieces(tempArray);
        br.close();
        return result;
    }
    
    @Override
    public String toString()
    {
        String result = new String();
        result += "Announce = " + this.getAnnounce() + "\n";
        result += "File Name = " + this.getFilename() + "\n";
        result += "File Size = " + this.getFileSize() + "\n";
        result += "Piece Length = " + this.getPieceLength() + "\n";
        result += "Pieces Amount = " + this.getPiecesAmount() + "\n";
        for (int i = 0; i < this.getPiecesAmount(); i++)
        {
            result += "Piece-" + i + " = " + this.getPieces().get(i) + "\n";
        }
        return result;
    }
    /**
     * @return the filename
     */
    public String getFilename() {
        return filename;
    }

    /**
     * @return the pieceLength
     */
    public int getPieceLength() {
        return pieceLength;
    }

    /**
     * @return the piece
     */
    public ArrayList<String> getPieces() {
        return pieces;
    }

    /**
     * @return the fileSize
     */
    public long getFileSize() {
        return fileSize;
    }

    /**
     * @param filename the filename to set
     */
    public void setFilename(String filename) {
        this.filename = filename;
    }

    /**
     * @param pieceLength the pieceLength to set
     */
    public void setPieceLength(int pieceLength) {
        this.pieceLength = pieceLength;
    }

    /**
     * @param piece the piece to set
     */
    public void setPieces(ArrayList<String> pieces) {
        this.pieces = pieces;
    }

    /**
     * @param fileSize the fileSize to set
     */
    public void setFileSize(long fileSize) {
        this.fileSize = fileSize;
    }

    /**
     * @return the piecesAmount
     */
    public int getPiecesAmount() {
        return piecesAmount;
    }

    /**
     * @param piecesAmount the piecesAmount to set
     */
    public void setPiecesAmount(int piecesAmount) {
        this.piecesAmount = piecesAmount;
    }

    /**
     * @return the announce
     */
    public String getAnnounce() {
        return announce;
    }

    /**
     * @param announce the announce to set
     */
    public void setAnnounce(String announce) {
        this.announce = announce;
    }
}
